#include "Common.h"
#include "ThreadCache.h"
#include "PageCache.h"
#include "ObjectPool.h"


static void* ConcurrentAlloc(size_t size)// static 防止多个cpp引用此头文件导致链接时的重定义错误
{
	if (size > MAX_BYTES)
	{
		size_t alignSize = SizeClass::RoundUp(size);// [TODO RoundUp > 256]
		size_t nPage = alignSize >> PAGE_SHIFT;

		PageCache::GetInstance()->_pageMtx.lock();
		Span* span = PageCache::GetInstance()->NewSpan(nPage);
		span->_objSize = size;
		PageCache::GetInstance()->_pageMtx.unlock();

		return (void*)(span->_pageId << PAGE_SHIFT);
	}
	if (pTLSThreadCache == nullptr)
	{
		static ObjectPool<ThreadCache> tcPool;
		//pTLSThreadCache = new ThreadCache;
		pTLSThreadCache = tcPool.New();
	}
	//cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;//验证TLS可以给每个线程分配不同的独立变量
	return pTLSThreadCache->Allocate(size);
}

static void ConcurrentFree(void *ptr)// 按道理说，不应要求size参数，此问题日后解决
{

	//PageCache::GetInstance()->_pageMtx.lock();
	Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
	size_t size = span->_objSize;
	//PageCache::GetInstance()->_pageMtx.unlock();
	//size_t size = span->_objSize;

	if (size > MAX_BYTES)
	{
		PageCache::GetInstance()->_pageMtx.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(span);
		PageCache::GetInstance()->_pageMtx.unlock();
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}

}
